package com.woniu.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.entity.EverOrder;
import com.woniu.entity.EverUser;
import com.woniu.mapper.EverUserMapper;
import com.woniu.service.IEverUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.catalina.User;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lkl
 * @since 2020-11-29
 */
@Service
@Transactional
public class EverUserServiceImpl extends ServiceImpl<EverUserMapper, EverUser> implements IEverUserService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Resource
    private EverUserMapper userMapper;

    @Qualifier("redisTemplate")
    @Autowired
    private RedisTemplate redisTemplate;

    //将数据放入ES
    @Override
    public void insertES() throws Exception {
        synchronized (this) {
            List<EverUser> users = userMapper.selectList(null);
            System.out.println("xzyou"+users.size());
            //把查询出来的数据放入es中
            BulkRequest bulkRequest = new BulkRequest();
            bulkRequest.timeout("2m");
            for (int i = 0; i < users.size(); i++) {
                bulkRequest.add(new IndexRequest("user_info").id(users.get(i).getUid()+"")
                        .source(JSON.toJSONString(users.get(i)), XContentType.JSON));
            }
            restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println("我来过了");
        }
        //System.out.println(bulk.hasFailures());

    }

    @Override
    public List<EverUser> findAllInEs() {
        return userMapper.selectList(null);

    }

    /**
     * 分页查询 高亮显示
     * @param user
     * @param pageNo
     * @param pageSize
     * @return
     */

    @Override
    public Map<String, Object> serachPageHighLight(EverUser user, Integer pageNo, Integer pageSize) throws Exception {
        //条件搜索
        //多条件搜索
        Map<String, Object> map=new HashMap<>();
        if (user.getUname()!=null && !"".equals(user.getUname())||user.getSex()!=null && !"".equals(user.getSex())){
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            SearchRequest searchRequest = new SearchRequest("user_info");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            //查询
            if (user.getUname()!=null && !"".equals(user.getUname())) {
                String str="*"+user.getUname()+"*";
                //匹配查询
                QueryBuilder matchQueryBuilder = new MatchQueryBuilder("uname",user.getUname());
                //模糊查询
                WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("uname",str);
                //精确查询
                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("uname", str);
                // boolQueryBuilder.should(termQueryBuilder);
                boolQueryBuilder.should(wildcardQueryBuilder);
                boolQueryBuilder.should(matchQueryBuilder);

                //高亮
                HighlightBuilder highlightBuilder = new HighlightBuilder();
                highlightBuilder.field("uname");
                highlightBuilder.requireFieldMatch(false);//多个高亮显示！
                highlightBuilder.preTags("<span style='color:red'>");
                highlightBuilder.postTags("</span>");
                //按照分数排序
                SortBuilder sortBuilder=new ScoreSortBuilder();
                sortBuilder.order(SortOrder.DESC);
                sourceBuilder.highlighter(highlightBuilder);
                sourceBuilder.sort(sortBuilder);
            }else{
                //按照uid进行倒序排序
                sourceBuilder.sort("uid", SortOrder.DESC);
            }
            //匹配查询
            if (user.getSex()!=null && !"".equals(user.getSex())) {
                QueryBuilder termQueryBuilder = QueryBuilders.matchQuery("sex", user.getSex());
                boolQueryBuilder.must(termQueryBuilder);
            }

            if (user==null){
                MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
                sourceBuilder.query(matchAllQueryBuilder);

            }else{
                sourceBuilder.query(boolQueryBuilder);
            }

            //设置超时时间
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
            //分页
            sourceBuilder.from((pageNo-1)*pageSize);
            sourceBuilder.size(pageSize);



            //执行搜索

            searchRequest.source(sourceBuilder);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            TotalHits totalHits = searchResponse.getHits().getTotalHits();
            System.out.println(totalHits);
            //解析结果
            ArrayList<Map<String, Object>> list = new ArrayList<>();
            //循环将结果放入Map
            for (SearchHit documentFields : searchResponse.getHits().getHits()) {

                Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
                HighlightField name = highlightFields.get("uname");
                Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();//原来的结果
                //解析高亮的字段,将原来的字段换为我们的高亮字段
                if (user.getUname()!=null) {
                    if (name!=null){
                        Text[] fragments = name.fragments();
                        String n_name="";
                        for (Text text : fragments) {
                            n_name += text;
                        }
                        sourceAsMap.put("uname", n_name);//替换
                    }
                }
                list.add(sourceAsMap);
            }
            map.put("list", list);
            map.put("total", totalHits);

        }else{
            QueryWrapper<EverUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.orderByDesc("creatTime");
            Page<EverUser> page = new Page<>(pageNo, pageSize);
            IPage<EverUser> pageData = userMapper.selectSLByManager(page, queryWrapper);
            System.out.println("总页数：" + pageData.getPages());
            System.out.println("总记录数：" + pageData.getTotal());
            List<EverUser> list = pageData.getRecords();
            map.put("list", list);
            Map<String, Object> map1=new HashMap<>();
            map1.put("value", pageData.getTotal());
            map.put("total", map1);
        }

        return map;
    }

    @Override
    public void insertList(List<EverUser> list) {
        for (EverUser everUser : list) {
            userMapper.insert(everUser);
        }
    }
    //查询所有的用户（无分页查询
    @Override
    public List<EverUser> searchAll() {
        Map<String, Object> map=new HashMap<>();
        List<EverUser> users = userMapper.selectList(null);

        return users;
    }

    //修改员工数据
    @Override
    public Integer updateOne(EverUser user) throws Exception {
        UpdateRequest updateRequest = new UpdateRequest("user_info", user.getUid()+"");
        updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        Thread.sleep(250);
        System.out.println(update.status());
        return userMapper.updateById(user);
    }

    //查一个
    @Override
    public Map<String, Object> findOne(EverUser user) throws Exception {

        //条件搜索
        SearchRequest searchRequest = new SearchRequest("user_info");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        //精准搜索
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("uid", user.getUid());
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //解析结果
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit documentFields : searchResponse.getHits().getHits()) {
            list.add(documentFields.getSourceAsMap());
        }

        return list.size()==0?null:list.get(0);

    }

    /**
     * 添加员工 默认密码123456
     * @param user
     * @return
     */
    @Override
    public String addUser(EverUser user) throws InterruptedException {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("idcard", user.getIdcard());
        List list = userMapper.selectList(queryWrapper);
        if (list.size()!=0){
            return "该身份证已被注册";
        }else {
            user.setUpwd("123456");
            userMapper.insert(user);
            Thread.sleep(250);
        }
        return "success";
    }

    /**
     * 根据id删除
     * @param uid
     * @return
     * @throws IOException
     */
    @Override
    public String deleteById(Long uid) throws Exception {
        DeleteRequest deleteRequest = new DeleteRequest("user_info", uid+"");
        deleteRequest.timeout("1s");
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        Thread.sleep(250);
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("uid", uid);
        userMapper.delete(queryWrapper);



        return "ok";
    }

    /**
     * 暂时不用
     * @param user
     * @return
     */
    @Override
    public List<EverUser> findByExample(EverUser user) {
        return  null;
    }

}
